home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / drdobbs / xsharp / ball / genball.c < prev    next >
Text File  |  1992-03-07  |  6KB  |  197 lines

  1. /* Generates the vertices for a ball approximated with polygonal
  2.    facets, in a form suitable for including into a C module. Vertices,
  3.    faces, and supporting info is generated, in the following format:
  4.  
  5. ----------------------------start------------------------------
  6. #define NUM_FACES <number of faces in object>
  7. #define NUM_VERTS <number of vertices in object>
  8.  
  9. Point3 Verts[] = { <vertices in object> };
  10.  
  11. static int Face0[] = { <vertex indexes for face, clockwise> };
  12. static int Face1[] = { <vertex indexes for face, clockwise> };
  13.                   :
  14. static int Face<n>[] = { <vertex indexes for face, clockwise> };
  15.  
  16. static int *VertNumList[] = { <ptr to vertex index list per face> };
  17. static int VertsInFace[] = { <# vertices in each face> };
  18. ----------------------------end--------------------------------
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <conio.h>
  23. #include <math.h>
  24. #include <string.h>
  25. #include "polygon.h"
  26.  
  27. #define PI  3.14159265358979323846
  28. #define DOUBLE_TO_FIXED(x) ((long) (x * 65536.0 + 0.5))
  29.  
  30. void main(void);
  31. void PrintVertex(struct Point3 *);
  32. void Print3Indexes(int, int, int, int);
  33. void Print4Indexes(int, int, int, int, int);
  34.  
  35. /* Used to rotate around the Y axis by one band's width */
  36. static double YXform[4][4] = {
  37.    {1.0, 0.0, 0.0, 0.0},
  38.    {0.0, 1.0, 0.0, 0.0},
  39.    {0.0, 0.0, 1.0, 0.0},
  40.    {0.0, 0.0, 0.0, 1.0}
  41. };
  42.  
  43. /* Used to rotate around the Z axis by one band's width */
  44. static double ZXform[4][4] = {
  45.    {1.0, 0.0, 0.0, 0.0},
  46.    {0.0, 1.0, 0.0, 0.0},
  47.    {0.0, 0.0, 1.0, 0.0},
  48.    {0.0, 0.0, 0.0, 1.0}
  49. };
  50.  
  51. static FILE *OutputFile;   /* where we'll write to */
  52.  
  53. void main()
  54. {
  55.    int Radius, Bands, i, j, LastIndex, BandsX2, LastBandStartIndex;
  56.    int TopBandStartIndex, BottomBandStartIndex, FaceNum;
  57.    struct Point3 BaseVec, BandVec, WorkingVec, TempVec;
  58.    char OutputFilename[130];
  59.    char Description[130];
  60.  
  61.    printf("Radius: ");
  62.    scanf("%d",&Radius);
  63.    printf("Bands: ");
  64.    scanf("%d",&Bands);
  65.    printf("Output file: ");
  66.    OutputFilename[0] = 127;
  67.    cgets(OutputFilename);
  68.    printf("\nBrief description: ");
  69.    Description[0] = 127;
  70.    cgets(Description);
  71.    printf("\n");
  72.  
  73.    BandsX2 = Bands*2;
  74.  
  75.    if ((OutputFile = fopen(&OutputFilename[2], "w")) == NULL) {
  76.       printf("Error\n");
  77.       exit(1);
  78.    }
  79.  
  80.    /* Descriptive comments */
  81.    fprintf(OutputFile, "/* %s */\n", &Description[2]);
  82.    fprintf(OutputFile, "/* Created with radius = %d, bands = %d */\n",
  83.          Radius, Bands);
  84.  
  85.    /* Defines for # of faces and vertices */
  86.    fprintf(OutputFile, "#define NUM_FACES %d\n", BandsX2*Bands);
  87.    fprintf(OutputFile, "#define NUM_VERTS %d\n\n",
  88.          BandsX2*(Bands-1)+2);
  89.  
  90.    /* Do the vertices */
  91.    fprintf(OutputFile, "Point3 Verts[] = {\n");
  92.  
  93.     /* Generate the rotation matrices */
  94.    AppendRotationY(YXform, PI / Bands);
  95.    AppendRotationZ(ZXform, PI / Bands);
  96.  
  97.    /* Do the point at the top */
  98.    BaseVec.X = 0.0;
  99.    BaseVec.Y = Radius;
  100.    BaseVec.Z = 0.0;
  101.    BaseVec.W = 1.0;
  102.    PrintVertex(&BaseVec);
  103.  
  104.    BandVec = BaseVec;
  105.  
  106.    /* Do the vertices in each band in turn */
  107.    for (i=1; i<Bands; i++) {
  108.       /* Rotate around Z to the next band's latitude */
  109.       XformVec(ZXform, (double *)&BandVec, (double *)&TempVec);
  110.       WorkingVec = BandVec = TempVec;
  111.         /* Do the vertices in this band */
  112.       for (j=0; j<BandsX2; j++) {
  113.          WorkingVec = TempVec;
  114.          PrintVertex(&WorkingVec);
  115.          /* Now rotate around Y to the next vertex's longitude */
  116.          XformVec(YXform, (double *)&WorkingVec, (double *)&TempVec);
  117.       }
  118.    }
  119.  
  120.    /* Do the point at the bottom */
  121.    BaseVec.Y = -Radius;
  122.    PrintVertex(&BaseVec);
  123.  
  124.    fprintf(OutputFile, "};\n\n");
  125.  
  126.    /* Do the vertex indexes for each face in each band */
  127.    FaceNum = 0;
  128.  
  129.    /* Vertex indexes in top band */
  130.    for (i=0; i<BandsX2; i++) {
  131.       Print3Indexes(FaceNum++, 0, ((i+1)%BandsX2)+1, i+1);
  132.    }
  133.  
  134.    /* Vertex indexes in middle bands */
  135.    for (j=0; j<(Bands-2); j++) {
  136.       TopBandStartIndex = j*BandsX2 + 1;
  137.       BottomBandStartIndex = (j+1)*BandsX2 + 1;
  138.         /* Indexes in this band */
  139.       for (i=0; i<BandsX2; i++) {
  140.          Print4Indexes(FaceNum++, i+TopBandStartIndex,
  141.                ((i+1)%BandsX2)+TopBandStartIndex,
  142.                ((i+1)%BandsX2)+BottomBandStartIndex,
  143.                i+BottomBandStartIndex);
  144.       }
  145.    }
  146.  
  147.    /* Vertex indexes in bottom band */
  148.    LastIndex = BandsX2*(Bands-1)+1;
  149.    LastBandStartIndex = BandsX2*(Bands-2)+1;
  150.    for (i=0; i<BandsX2; i++) {
  151.       Print3Indexes(FaceNum++, LastBandStartIndex+i,
  152.             LastBandStartIndex+((i+1)%BandsX2), LastIndex);
  153.    }
  154.  
  155.    /* Do the list of pointers to index arrays for each face */
  156.    fprintf(OutputFile, "\nstatic int *VertNumList[] = {\n");
  157.    for (i=0; i<(BandsX2*Bands); i++) {
  158.       fprintf(OutputFile, "Face%d,\n", i);
  159.    }
  160.    fprintf(OutputFile, "};\n");
  161.  
  162.    /* Do the # of vertices in each face (3 for the top and bottom
  163.       bands, 4 for the rest) */
  164.    fprintf(OutputFile, "\nstatic int VertsInFace[] = {\n");
  165.    for (i=0; i<BandsX2; i++) fprintf(OutputFile, "3,\n");
  166.    for (i=0; i<(BandsX2*(Bands-2)); i++) fprintf(OutputFile, "4,\n");
  167.    for (i=0; i<BandsX2; i++) fprintf(OutputFile, "3,\n");
  168.    fprintf(OutputFile, "};\n");
  169.  
  170.    exit(0);
  171. }
  172.  
  173. /* Prints the array of indexes for a 4-vertex face */
  174. void Print4Indexes(int FaceNum, int V1, int V2, int V3, int V4)
  175. {
  176.       fprintf(OutputFile, "static int Face%d[] = {%d,%d,%d,%d};\n",
  177.             FaceNum, V1, V2, V3, V4);
  178. }
  179.  
  180. /* Prints the array of indexes for a 3-vertex face */
  181. void Print3Indexes(int FaceNum, int V1, int V2, int V3)
  182. {
  183.       fprintf(OutputFile, "static int Face%d[] = {%d,%d,%d};\n",
  184.             FaceNum, V1, V2, V3);
  185. }
  186.  
  187. /* Prints a vertex, in 16.16 fixed-point form */
  188. void PrintVertex(struct Point3 *Vec)
  189. {
  190.    long X = DOUBLE_TO_FIXED(Vec->X);
  191.    long Y = DOUBLE_TO_FIXED(Vec->Y);
  192.    long Z = DOUBLE_TO_FIXED(Vec->Z);
  193.  
  194.    fprintf(OutputFile, "{%ld, %ld, %ld},\n", X, Y, Z);
  195. }
  196.  
  197.